package com.ruoyi.web.controller.pay;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.TypeReference;
import com.paypal.api.payments.*;
import com.paypal.base.rest.APIContext;
import com.paypal.base.rest.PayPalRESTException;
import com.ruoyi.common.PayPalUtil.PaypalPaymentIntent;
import com.ruoyi.common.PayPalUtil.PaypalPaymentMethod;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.model.VsUser;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.BigDecimalUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.ip.URLUtils;
import com.ruoyi.system.domain.config.VsDramasConfig;
import com.ruoyi.system.domain.reseller.VsDramasReseller;
import com.ruoyi.system.domain.reseller.VsDramasResellerBind;
import com.ruoyi.system.domain.reseller.VsDramasResellerLog;
import com.ruoyi.system.domain.reseller.VsDramasResellerOrder;
import com.ruoyi.system.domain.usable.VsDramasUsable;
import com.ruoyi.system.domain.usable.VsDramasUsableOrder;
import com.ruoyi.system.domain.user.VsDramasUserWalletLog;
import com.ruoyi.system.domain.video.VsLang;
import com.ruoyi.system.domain.vip.VsDramasVip;
import com.ruoyi.system.domain.vip.VsDramasVipOrder;
import com.ruoyi.system.mapper.reseller.VsDramasResellerBindMapper;
import com.ruoyi.system.mapper.reseller.VsDramasResellerOrderMapper;
import com.ruoyi.system.mapper.usable.VsDramasUsableOrderMapper;
import com.ruoyi.system.mapper.user.VsUserMapper;
import com.ruoyi.system.mapper.vip.VsDramasVipOrderMapper;
import com.ruoyi.system.service.config.IVsDramasConfigService;
import com.ruoyi.system.service.reseller.IVsDramasResellerBindService;
import com.ruoyi.system.service.reseller.IVsDramasResellerLogService;
import com.ruoyi.system.service.reseller.IVsDramasResellerOrderService;
import com.ruoyi.system.service.reseller.IVsDramasResellerService;
import com.ruoyi.system.service.usable.IVsDramasUsableOrderService;
import com.ruoyi.system.service.usable.IVsDramasUsableService;
import com.ruoyi.system.service.user.IVsDramasUserWalletLogService;
import com.ruoyi.system.service.user.IVsUserService;
import com.ruoyi.system.service.video.IVsLangService;
import com.ruoyi.system.service.vip.IVsDramasVipOrderService;
import com.ruoyi.system.service.vip.IVsDramasVipService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
 * This file is part of 南阳迈特网络科技有限公司.
 * @company  南阳迈特网络科技有限公司
 * @link     https://www.nymaite.com
 * @document https://product.nymaite.cn
 * @contact  service@nymaite.com
 * @author nymaite
 */
@RestController
public class PayPalController {

    private Logger log = LoggerFactory.getLogger(getClass());

    @Autowired
    private APIContext apiContext;

    @Value("${pay.paypal.PAYPAL_SUCCESS_URL}")
    private String PAYPAL_SUCCESS_URL;

    @Value("${pay.paypal.PAYPAL_CANCEL_URL}")
    private String PAYPAL_CANCEL_URL;

    @Autowired
    private RedisCache redisCache;

    @Autowired
    private IVsLangService vsLangService;

    @Autowired
    private IVsDramasVipService vsDramasVipService;

    @Autowired
    private IVsDramasUsableService vsDramasUsableService;

    @Autowired
    private IVsDramasResellerService vsDramasResellerService;

    @Autowired
    private VsDramasResellerOrderMapper vsDramasResellerOrderMapper;

    @Autowired
    private VsDramasUsableOrderMapper vsDramasUsableOrderMapper;

    @Autowired
    private VsDramasVipOrderMapper vsDramasVipOrderMapper;

    @Autowired
    private VsUserMapper vsUserMapper;

    @Autowired
    private IVsDramasResellerBindService vsDramasResellerBindService;

    @Autowired
    private IVsDramasResellerLogService vsDramasResellerLogService;

    @Autowired
    private IVsDramasUserWalletLogService vsDramasUserWalletLogService;

    @Autowired
    private IVsDramasConfigService vsDramasConfigService;

    @Transactional
    @PostMapping("/payPal")
    public AjaxResult toPay(@RequestBody Map<String, String> map, HttpServletRequest request){

        String baseURl = URLUtils.getBaseURl(request);

        String cancelUrl = baseURl + PAYPAL_CANCEL_URL;
        log.info(cancelUrl);
        String successlUrl = baseURl + PAYPAL_SUCCESS_URL;
        log.info(successlUrl);
        String langId = request.getHeader("Lang-Id");
        VsLang lang = vsLangService.selectVsLangById(langId);
        String payAmount = null;
        String currency = null;
        String description = null;
        String cancel_url = map.get("cancel_url");
        String return_url = map.get("return_url");
        String orderSn = map.get("orderSn");
        String platform = map.get("payment");
        String verifyKey = "PayPalUserId:"+apiContext.getAccessToken();
        redisCache.setCacheObject(verifyKey, orderSn);
        String substring = orderSn.substring(0, 1);
        if("A".equals(substring)){
            VsDramasVipOrder vipOrder = new VsDramasVipOrder();
            vipOrder.setOrderSn(orderSn);
            List<VsDramasVipOrder> vsDramasVipOrders = vsDramasVipOrderMapper.selectVsDramasVipOrderList(vipOrder);
            if (vsDramasVipOrders.isEmpty()) {
                return AjaxResult.error("未查询到VIP订单信息！");
            }
            VsDramasVip vsDramasVip = vsDramasVipService.selectVsDramasVipById(vsDramasVipOrders.get(0).getVipId());
            payAmount = String.valueOf(vsDramasVip.getPrice());
            currency = vsDramasVip.getVsLang().getCurrency();
            description = vsDramasVip.getTitle();
        } else if ("U".equals(substring)) {
            VsDramasUsableOrder usableOrder = new VsDramasUsableOrder();
            usableOrder.setOrderSn(orderSn);
            List<VsDramasUsableOrder> vsDramasUsableOrders = vsDramasUsableOrderMapper.selectVsDramasUsableOrderList(usableOrder);
            if (vsDramasUsableOrders.isEmpty()) {
                return AjaxResult.error("未查询到积分订单信息！");
            }
            VsDramasUsable vsDramasUsable = vsDramasUsableService.selectVsDramasUsableById(vsDramasUsableOrders.get(0).getUsableId());
            payAmount = String.valueOf(vsDramasUsable.getPrice());
            currency = vsDramasUsable.getVsLangInfo().getCurrency();
            description = vsDramasUsable.getTitle();
        } else if ("R".equals(substring))  {
            VsDramasResellerOrder resellerOrder = new VsDramasResellerOrder();
            resellerOrder.setOrderSn(orderSn);
            List<VsDramasResellerOrder> vsDramasResellerOrders = vsDramasResellerOrderMapper.selectVsDramasResellerOrderList(resellerOrder);
            if (vsDramasResellerOrders.isEmpty()) {
                return AjaxResult.error("未查询到分销订单信息！");
            }
            VsDramasReseller vsDramasReseller = vsDramasResellerService.selectVsDramasResellerById(vsDramasResellerOrders.get(0).getResellerId());
            payAmount = String.valueOf(vsDramasReseller.getPrice());
            currency = vsDramasReseller.getVsLangInfo().getCurrency();
            description = vsDramasReseller.getName();
        }
        if(payAmount == null || currency == null || description == null) {
            return AjaxResult.error("未找到相关付费信息！");
        }

        VsDramasConfig config = new VsDramasConfig();
        config.setName("paypal");
        List<VsDramasConfig> paypalConfigs = vsDramasConfigService.selectVsDramasConfigList(config);
        if (paypalConfigs.size() == 0) {
            return AjaxResult.error("未找到相关支付配置信息！");
        }
        com.alibaba.fastjson2.JSONObject paypalConfig = com.alibaba.fastjson2.JSONObject.parseObject(paypalConfigs.get(0).getValue());
        String webhook = paypalConfig.getString("webhook");
        PayPalPaymentConfig.updateConfig(webhook + return_url,webhook + cancel_url);

        //将价格转为支付金额类型
        BigDecimal amount = new BigDecimal(payAmount);
        try {
            Payment payment = createPayment(
                    amount,
                    currency,
                    PaypalPaymentMethod.paypal,
                    PaypalPaymentIntent.sale,
                    description,
                    cancelUrl,
                    successlUrl
            );
            //修改订单金额 & 支付的流水号
            int i = 0;
            if ("A".equals(substring)) {
                VsDramasVipOrder vipOrder = new VsDramasVipOrder();
                vipOrder.setOrderSn(orderSn);
                vipOrder.setPayType(platform);
                vipOrder.setPayFee(amount);
                vipOrder.setCurrency(currency);
                vipOrder.setUpdatetime(System.currentTimeMillis());
                i = vsDramasVipOrderMapper.updateVipOrderInfo(vipOrder);
            } else if ("U".equals(substring)) {
                VsDramasUsableOrder usableOrder = new VsDramasUsableOrder();
                usableOrder.setOrderSn(orderSn);
                usableOrder.setPayType(platform);
                usableOrder.setPayFee(amount);
                usableOrder.setCurrency(currency);
                usableOrder.setUpdatetime(System.currentTimeMillis());
                i = vsDramasUsableOrderMapper.updateUsableOrderInfo(usableOrder);
            } else {
                VsDramasResellerOrder resellerOrder = new VsDramasResellerOrder();
                resellerOrder.setOrderSn(orderSn);
                resellerOrder.setPayType(platform);
                resellerOrder.setPayFee(amount);
                resellerOrder.setCurrency(currency);
                resellerOrder.setUpdatetime(System.currentTimeMillis());
                i = vsDramasResellerOrderMapper.updateResellerOrderInfo(resellerOrder);
            }
            if (i == 0) {
                return AjaxResult.error("提交订单信息失败！");
            }
            log.info("支付金额："+payAmount);
            log.info("订单号："+payment.getId());

            for (Links links : payment.getLinks()) {
                if (links.getRel().equals("approval_url")) {
                    return AjaxResult.success(payment);
                }
            }
        } catch (PayPalRESTException e) {
            //保存paypal预支付异常信息 .......
            log.error(e.getMessage());
            return AjaxResult.error(e.getMessage());
        }
        return AjaxResult.error("支付错误！");
    }


    /**
     * PayPal 支付成功 回调
     * @param response
     * @param paymentId
     * @param payerId
     */
    @Transactional
    @GetMapping("/callback/success")
    public void successPay(HttpServletResponse response, @RequestParam("paymentId") String paymentId, @RequestParam("PayerID") String payerId) {
        log.info("================================payPal 回调成功===================================");
        log.info(apiContext.getAccessToken());
        try {

            redisCache.redisTemplate.setKeySerializer(new StringRedisSerializer());

            if (!redisCache.hasKey("PayPalUserId:" + apiContext.getAccessToken())) {
                throw new RuntimeException("订单信息不存在");
            }
            Payment payment = executePayment(paymentId,payerId);

            if (payment.getState().equals("approved")) {
                //修改订单状态
                Object cacheObject = redisCache.getCacheObject("PayPalUserId:" + apiContext.getAccessToken());
                String orderSn = cacheObject.toString();
                String substring = orderSn.substring(0, 1);
                if("A".equals(substring)){
                    VsDramasVipOrder vipOrder = new VsDramasVipOrder();
                    vipOrder.setOrderSn(orderSn);
                    vipOrder.setStatus(1L);
                    vipOrder.setTransactionId(paymentId);
                    String jsonString = JSON.toJSONString(payment);
                    vipOrder.setPaymentJson(jsonString);
                    vipOrder.setPaytime(System.currentTimeMillis());
                    vipOrder.setUpdatetime(System.currentTimeMillis());
                    int i = vsDramasVipOrderMapper.updateVipOrderInfo(vipOrder);
                    if (i > 0) {
                        VsDramasVipOrder userOrder = new VsDramasVipOrder();
                        userOrder.setOrderSn(orderSn);
                        List<VsDramasVipOrder> orders = vsDramasVipOrderMapper.selectVsDramasVipOrderList(userOrder);
                        VsUser user = new VsUser();
                        user.setId(Long.valueOf(orders.get(0).getUserId()));
                        user.setVipExpiretime(orders.get(0).getTimes());
                        vsUserMapper.updateVsUserUsable(user);
                        redisCache.deleteObject("PayPalUserId:" + apiContext.getAccessToken());
                    }
                } else if ("U".equals(substring)) {
                    VsDramasUsableOrder usableOrder = new VsDramasUsableOrder();
                    usableOrder.setOrderSn(orderSn);
                    usableOrder.setStatus(1);
                    usableOrder.setTransactionId(paymentId);
                    String jsonString = JSON.toJSONString(payment);
                    usableOrder.setPaymentJson(jsonString);
                    usableOrder.setPaytime(System.currentTimeMillis());
                    usableOrder.setUpdatetime(System.currentTimeMillis());
                    int i = vsDramasUsableOrderMapper.updateUsableOrderInfo(usableOrder);
                    if (i > 0) {
                        VsDramasUsableOrder userOrder = new VsDramasUsableOrder();
                        userOrder.setOrderSn(orderSn);
                        List<VsDramasUsableOrder> orders = vsDramasUsableOrderMapper.selectVsDramasUsableOrderList(userOrder);
                        VsUser user = new VsUser();
                        user.setId(Long.valueOf(orders.get(0).getUserId()));
                        user.setUsable(Long.valueOf(orders.get(0).getUsable()));
                        vsUserMapper.updateVsUserUsable(user);
                        redisCache.deleteObject("PayPalUserId:" + apiContext.getAccessToken());
                    }
                } else {
                    VsDramasResellerOrder resellerOrder = new VsDramasResellerOrder();
                    resellerOrder.setOrderSn(orderSn);
                    resellerOrder.setStatus(1);
                    resellerOrder.setTransactionId(paymentId);
                    String jsonString = JSON.toJSONString(payment);
                    resellerOrder.setPaymentJson(jsonString);
                    resellerOrder.setPaytime(System.currentTimeMillis());
                    resellerOrder.setUpdatetime(System.currentTimeMillis());
                    int i = vsDramasResellerOrderMapper.updateResellerOrderInfo(resellerOrder);
                    if (i > 0) {
                        int order = resellerOrder(orderSn);
                        if (order > 0) {
                            int distributionOrder = distributionOrder(orderSn);
                            if (distributionOrder > 0) {
                                response.sendRedirect(PayPalPaymentConfig.getPaypalSuccessPage());
                            }
                        }
                        redisCache.deleteObject("PayPalUserId:" + apiContext.getAccessToken());
                    }
                }

            }else{
                response.sendRedirect(PayPalPaymentConfig.getPaypalCancelPage());
            }

        } catch (PayPalRESTException e) {
            log.info("!!!!!!!!!!!!!!支付回调失败 异常!!!!!!!!!!!!!!");
            log.error(e.getMessage());
            log.info("!!!!!!!!!!!!!!支付回调失败 异常!!!!!!!!!!!!!!");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * paypal 回调 取消支付
     * @param response
     * @throws IOException
     */
    @Transactional
    @GetMapping("/callback/cancel")
    public void cancelPay(HttpServletResponse response) throws IOException {
        log.info("================================payPal 取消支付===================================");

        redisCache.redisTemplate.setKeySerializer(new StringRedisSerializer());

        if (!redisCache.hasKey("PayPalUserId:" + apiContext.getAccessToken())) {
            throw new RuntimeException("订单信息不存在");
        }
        Object cacheObject = redisCache.getCacheObject("PayPalUserId:" + apiContext.getAccessToken());
        String orderSn = cacheObject.toString();
        String substring = orderSn.substring(0, 1);
        if("A".equals(substring)){
            VsDramasVipOrder vipOrder = new VsDramasVipOrder();
            vipOrder.setOrderSn(orderSn);
            vipOrder.setStatus(-1L);
            vipOrder.setUpdatetime(System.currentTimeMillis());
            vsDramasVipOrderMapper.updateVipOrderInfo(vipOrder);
        } else if ("U".equals(substring)) {
            VsDramasUsableOrder usableOrder = new VsDramasUsableOrder();
            usableOrder.setOrderSn(orderSn);
            usableOrder.setStatus(-1);
            usableOrder.setUpdatetime(System.currentTimeMillis());
            vsDramasUsableOrderMapper.updateUsableOrderInfo(usableOrder);
        } else if ("R".equals(substring)) {
            VsDramasResellerOrder resellerOrder = new VsDramasResellerOrder();
            resellerOrder.setOrderSn(orderSn);
            resellerOrder.setStatus(-1);
            resellerOrder.setUpdatetime(System.currentTimeMillis());
            vsDramasResellerOrderMapper.updateResellerOrderInfo(resellerOrder);
        }
        redisCache.deleteObject("PayPalUserId:" + apiContext.getAccessToken());

        response.sendRedirect(PayPalPaymentConfig.getPaypalCancelPage());
    }

    /**
     *
     * @param total
     * @param currency
     * @param method
     * @param intent
     * @param description
     * @param cancelUrl
     * @param successUrl
     * @return
     * @throws PayPalRESTException
     */
    public Payment createPayment(BigDecimal total, String currency, PaypalPaymentMethod method, PaypalPaymentIntent intent,
                                 String description, String cancelUrl, String successUrl) throws PayPalRESTException {
        Amount amount = new Amount();
        amount.setCurrency(currency);
        amount.setTotal(String.format("%.2f", total));

        Transaction transaction = new Transaction();
        transaction.setDescription(description);
        transaction.setAmount(amount);

        List<Transaction> transactions = new ArrayList<>();
        transactions.add(transaction);

        Payer payer = new Payer();
        payer.setPaymentMethod(method.toString());

        Payment payment = new Payment();
        payment.setIntent(intent.toString());
        payment.setPayer(payer);
        payment.setTransactions(transactions);
        RedirectUrls redirectUrls = new RedirectUrls();
        redirectUrls.setCancelUrl(cancelUrl);
        redirectUrls.setReturnUrl(successUrl);
        payment.setRedirectUrls(redirectUrls);

        return payment.create(apiContext);
    }

    /**
     *
     * @param paymentId
     * @param payerId
     * @return
     * @throws PayPalRESTException
     */
    public Payment executePayment(String paymentId, String payerId) throws PayPalRESTException {
        Payment payment = new Payment();
        payment.setId(paymentId);
        PaymentExecution paymentExecute = new PaymentExecution();
        paymentExecute.setPayerId(payerId);
        return payment.execute(apiContext, paymentExecute);
    }

    // 这个是保存分销商记录的方法
    private int resellerOrder(String orderSn) {
        VsDramasResellerOrder userOrder = new VsDramasResellerOrder();
        userOrder.setOrderSn(orderSn);
        List<VsDramasResellerOrder> orders = vsDramasResellerOrderMapper.selectVsDramasResellerOrderList(userOrder);
        if (orders.size() > 0) {
            VsDramasReseller reseller = vsDramasResellerService.selectVsDramasResellerById(orders.get(0).getResellerId());
            VsDramasResellerBind resellerBind = new VsDramasResellerBind();
            resellerBind.setResellerId(Long.valueOf(reseller.getId()));
            resellerBind.setUserId(SecurityUtils.getLoginUser().getVsUser().getId());
            resellerBind.setLevel(Long.valueOf(reseller.getLevel()));
            resellerBind.setExpiretime(orders.get(0).getTimes());
            String s = JSON.toJSONString(reseller);
            resellerBind.setResellerJson(s);
            resellerBind.setCreatetime(System.currentTimeMillis());
            resellerBind.setUpdatetime(System.currentTimeMillis());
            VsDramasResellerBind isBind = new VsDramasResellerBind();
            isBind.setUserId(SecurityUtils.getLoginUser().getVsUser().getId());
            List<VsDramasResellerBind> resellerBinds = vsDramasResellerBindService.selectVsDramasResellerBindList(isBind);
            // 如果当前用户以前充值过分销商，那就覆盖之前的分销商相关权益信息，否则就新增该用户的分销商相关权益信息
            if (resellerBinds.size() > 0) {
                return vsDramasResellerBindService.updateUserResellerBind(resellerBind);
            }
            return vsDramasResellerBindService.insertVsDramasResellerBind(resellerBind);
        }
        return 0;
    }

    // 这个是vip、积分、分销相关给上级和上上级分钱的方法
    private int distributionOrder(String orderSn) {
        try {
            VsUser vsUser = SecurityUtils.getLoginUser().getVsUser();
            if (vsUser.getParentUserId() == null) {
                return 0;
            }
            // 先查询出上级和上上级的信息
            VsUser parentUser = vsUserMapper.selectVsUserById(vsUser.getParentUserId());
            VsUser superUser = vsUserMapper.selectVsUserById(parentUser.getParentUserId());
            VsDramasResellerBind vsDramasResellerBind = new VsDramasResellerBind();
            vsDramasResellerBind.setUserId(vsUser.getParentUserId());
            List<VsDramasResellerBind> binds = vsDramasResellerBindService.selectVsDramasResellerBindList(vsDramasResellerBind);
            int i = 0;
            if (!binds.isEmpty()) {
                Long expiretime = binds.get(0).getExpiretime();
                // 如果不等于0或者小于当前时间就代表没有分销的权限直接跳过
                if (expiretime != 0 || System.currentTimeMillis() > expiretime) {
                    i++;
                    if (parentUser.getParentUserId() == null) {
                        return 0;
                    }
                }
            }
            VsDramasResellerBind parentUserBind = new VsDramasResellerBind();
            parentUserBind.setUserId(parentUser.getParentUserId());
            List<VsDramasResellerBind> parentBinds = vsDramasResellerBindService.selectVsDramasResellerBindList(parentUserBind);
            int superior = 0;
            if (!parentBinds.isEmpty()) {
                Long parentExpiretime = parentBinds.get(0).getExpiretime();
                // 如果进来了那就代表上级也不是分销商
                if (parentExpiretime != 0 || System.currentTimeMillis() > parentExpiretime) {
                    superior+=1;
                }
            }
            // 如果上级和上上级都不是分销商那就直接不往下走
            if (i > 0 && superior > 0) {
                return 0;
            }
            int parentWalletLogs = 0;
            int superWalletLogs = 0;
            String substring = orderSn.substring(0, 1);
            if("A".equals(substring)){
                VsDramasVipOrder vipOrder = new VsDramasVipOrder();
                vipOrder.setOrderSn(orderSn);
                List<VsDramasVipOrder> vsDramasVipOrders = vsDramasVipOrderMapper.selectVsDramasVipOrderList(vipOrder);
                VsLang vsLang = vsLangService.selectVsLangById(String.valueOf(vsDramasVipOrders.get(0).getLangId()));
                // i=0就代表当前用户的上级是分销商，再往下走分销逻辑，如果不是则不走分销逻辑
                if (i == 0) {
                    VsDramasResellerLog resellerLog = new VsDramasResellerLog();
                    resellerLog.setType("direct");
                    resellerLog.setResellerUserId(Math.toIntExact(vsUser.getParentUserId()));
                    resellerLog.setUserId(Math.toIntExact(vsUser.getId()));
                    resellerLog.setLangId(Integer.valueOf(vsLang.getId()));
                    resellerLog.setPayMoney(vsDramasVipOrders.get(0).getTotalFee());
                    Map<String, String> map = JSON.parseObject(binds.get(0).getResellerJson(), new TypeReference<Map<String, String>>(){});
                    BigDecimal ratio = new BigDecimal(map.get("direct"));
                    resellerLog.setRatio(ratio);
                    // 将其除以 100
                    BigDecimal result = ratio.divide(new BigDecimal("100"));
                    BigDecimal money = vsDramasVipOrders.get(0).getTotalFee().multiply(result);
                    resellerLog.setCurrency(vsLang.getCurrency());
                    resellerLog.setExchangeRate(vsLang.getExchangeRate());
//                    money.multiply(new BigDecimal(vsLang.getExchangeRate()));
                    long l = BigDecimalUtils.calculateBigDecimalConversionToLong(money, vsLang.getExchangeRate());
                    if (l == 0) {
                        throw new Exception("BigDecimal value is out of long range.");
                    }
                    resellerLog.setMoney(BigDecimal.valueOf(l));
                    resellerLog.setTotalMoney(l);
                    resellerLog.setOrderType("vip");
                    resellerLog.setOrderId(Math.toIntExact(vsDramasVipOrders.get(0).getId()));
                    resellerLog.setCreatetime(System.currentTimeMillis());
                    int vipLog = vsDramasResellerLogService.insertVsDramasResellerLog(resellerLog);
                    // 分销记录保存成功后就开始给对应用户钱包加钱
                    if (vipLog > 0) {
                        VsDramasUserWalletLog walletLog = new VsDramasUserWalletLog();
                        walletLog.setUserId(vsUser.getParentUserId());
                        walletLog.setWallet(BigDecimal.valueOf(l));
                        walletLog.setWalletType("money");
                        walletLog.setType("commission_income");
                        walletLog.setBefore(parentUser.getMoney());
                        walletLog.setAfter(parentUser.getMoney().add(BigDecimal.valueOf(l)));
                        walletLog.setItemId(String.valueOf(vsDramasVipOrders.get(0).getVipId()));
                        walletLog.setMemo("直接分销佣金");
                        // 创建一个 JSONObject 对象，将字段值放入
                        JSONObject jsonObject = new JSONObject();
                        jsonObject.put("reseller_log_id", resellerLog.getId());
                        jsonObject.put("user_id", vsUser.getId());
                        jsonObject.put("parent_id", vsUser.getParentUserId());
                        jsonObject.put("reseller_user_id", vsUser.getParentUserId());
                        // 将 JSONObject 转换为 JSON 字符串
                        String jsonString = jsonObject.toJSONString();
                        walletLog.setExt(jsonString);
                        walletLog.setOperType("system");
                        walletLog.setOperId(0L);
                        walletLog.setCreatetime(System.currentTimeMillis());
                        walletLog.setUpdatetime(System.currentTimeMillis());
                        parentWalletLogs = vsDramasUserWalletLogService.insertVsDramasUserWalletLog(walletLog);
                    }
                }
                // 如果superior=0就代表上上级是分销商，再往下走分销逻辑，如果不是则不走分销逻辑
                if (superior == 0) {
                    VsDramasResellerLog resellerLog = new VsDramasResellerLog();
                    resellerLog.setType("indirect");
                    resellerLog.setResellerUserId(Math.toIntExact(vsUser.getParentUserId()));
                    resellerLog.setUserId(Math.toIntExact(vsUser.getId()));
                    resellerLog.setLangId(Integer.valueOf(vsLang.getId()));
                    resellerLog.setPayMoney(vsDramasVipOrders.get(0).getTotalFee());
                    Map<String, String> map = JSON.parseObject(binds.get(0).getResellerJson(), new TypeReference<Map<String, String>>(){});
                    BigDecimal ratio = new BigDecimal(map.get("indirect"));
                    resellerLog.setRatio(ratio);
                    // 将其除以 100
                    BigDecimal result = ratio.divide(new BigDecimal("100"));
                    BigDecimal money = vsDramasVipOrders.get(0).getTotalFee().multiply(result);
                    resellerLog.setCurrency(vsLang.getCurrency());
                    resellerLog.setExchangeRate(vsLang.getExchangeRate());
//                    money.multiply(new BigDecimal(vsLang.getExchangeRate()));
                    long l = BigDecimalUtils.calculateBigDecimalConversionToLong(money, vsLang.getExchangeRate());
                    if (l == 0) {
                        throw new Exception("BigDecimal value is out of long range.");
                    }
                    resellerLog.setMoney(BigDecimal.valueOf(l));
                    resellerLog.setTotalMoney(l);
                    resellerLog.setOrderType("vip");
                    resellerLog.setOrderId(Math.toIntExact(vsDramasVipOrders.get(0).getId()));
                    resellerLog.setCreatetime(System.currentTimeMillis());
                    int vipLog = vsDramasResellerLogService.insertVsDramasResellerLog(resellerLog);
                    // 分销记录保存成功后就开始给对应用户钱包加钱
                    if (vipLog > 0) {
                        VsDramasUserWalletLog walletLog = new VsDramasUserWalletLog();
                        walletLog.setUserId(superUser.getId());
                        walletLog.setWallet(BigDecimal.valueOf(l));
                        walletLog.setWalletType("money");
                        walletLog.setType("commission_income");
                        walletLog.setBefore(superUser.getMoney());
                        walletLog.setAfter(superUser.getMoney().add(BigDecimal.valueOf(l)));
                        walletLog.setItemId(String.valueOf(vsDramasVipOrders.get(0).getVipId()));
                        walletLog.setMemo("间接分销佣金");
                        // 创建一个 JSONObject 对象，将字段值放入
                        JSONObject jsonObject = new JSONObject();
                        jsonObject.put("reseller_log_id", resellerLog.getId());
                        jsonObject.put("user_id", vsUser.getId());
                        jsonObject.put("parent_id", vsUser.getParentUserId());
                        jsonObject.put("reseller_user_id", superUser.getId());
                        // 将 JSONObject 转换为 JSON 字符串
                        String jsonString = jsonObject.toJSONString();
                        walletLog.setExt(jsonString);
                        walletLog.setOperType("system");
                        walletLog.setOperId(0L);
                        walletLog.setCreatetime(System.currentTimeMillis());
                        walletLog.setUpdatetime(System.currentTimeMillis());
                        superWalletLogs = vsDramasUserWalletLogService.insertVsDramasUserWalletLog(walletLog);
                    }
                }
                return parentWalletLogs + superWalletLogs;
            } else if ("U".equals(substring)) {
                VsDramasUsableOrder usableOrder = new VsDramasUsableOrder();
                usableOrder.setOrderSn(orderSn);
                List<VsDramasUsableOrder> usableOrders = vsDramasUsableOrderMapper.selectVsDramasUsableOrderList(usableOrder);
                VsLang vsLang = vsLangService.selectVsLangById(String.valueOf(usableOrders.get(0).getLangId()));
                if (i == 0) {
                    VsDramasResellerLog resellerLog = new VsDramasResellerLog();
                    resellerLog.setType("direct");
                    resellerLog.setResellerUserId(Math.toIntExact(vsUser.getParentUserId()));
                    resellerLog.setUserId(Math.toIntExact(vsUser.getId()));
                    resellerLog.setLangId(Integer.valueOf(vsLang.getId()));
                    resellerLog.setPayMoney(usableOrders.get(0).getTotalFee());
                    Map<String, String> map = JSON.parseObject(binds.get(0).getResellerJson(), new TypeReference<Map<String, String>>(){});
                    BigDecimal ratio = new BigDecimal(map.get("direct"));
                    resellerLog.setRatio(ratio);
                    // 将其除以 100
                    BigDecimal result = ratio.divide(new BigDecimal("100"));
                    BigDecimal money = usableOrders.get(0).getTotalFee().multiply(result);
                    resellerLog.setCurrency(vsLang.getCurrency());
                    resellerLog.setExchangeRate(vsLang.getExchangeRate());
//                    money.multiply(new BigDecimal(vsLang.getExchangeRate()));
                    long l = BigDecimalUtils.calculateBigDecimalConversionToLong(money, vsLang.getExchangeRate());
                    if (l == 0) {
                        throw new Exception("BigDecimal value is out of long range.");
                    }
                    resellerLog.setMoney(BigDecimal.valueOf(l));
                    resellerLog.setTotalMoney(l);
                    resellerLog.setOrderType("vip");
                    resellerLog.setOrderId(Math.toIntExact(usableOrders.get(0).getId()));
                    resellerLog.setCreatetime(System.currentTimeMillis());
                    int vipLog = vsDramasResellerLogService.insertVsDramasResellerLog(resellerLog);
                    // 分销记录保存成功后就开始给对应用户钱包加钱
                    if (vipLog > 0) {
                        VsDramasUserWalletLog walletLog = new VsDramasUserWalletLog();
                        walletLog.setUserId(vsUser.getParentUserId());
                        walletLog.setWallet(BigDecimal.valueOf(l));
                        walletLog.setWalletType("money");
                        walletLog.setType("commission_income");
                        walletLog.setBefore(parentUser.getMoney());
                        walletLog.setAfter(parentUser.getMoney().add(BigDecimal.valueOf(l)));
                        walletLog.setItemId(String.valueOf(usableOrders.get(0).getUsableId()));
                        walletLog.setMemo("直接分销佣金");
                        // 创建一个 JSONObject 对象，将字段值放入
                        JSONObject jsonObject = new JSONObject();
                        jsonObject.put("reseller_log_id", resellerLog.getId());
                        jsonObject.put("user_id", vsUser.getId());
                        jsonObject.put("parent_id", vsUser.getParentUserId());
                        jsonObject.put("reseller_user_id", vsUser.getParentUserId());
                        // 将 JSONObject 转换为 JSON 字符串
                        String jsonString = jsonObject.toJSONString();
                        walletLog.setExt(jsonString);
                        walletLog.setOperType("system");
                        walletLog.setOperId(0L);
                        walletLog.setCreatetime(System.currentTimeMillis());
                        walletLog.setUpdatetime(System.currentTimeMillis());
                        parentWalletLogs = vsDramasUserWalletLogService.insertVsDramasUserWalletLog(walletLog);
                    }
                }
                if (superior == 0) {
                    VsDramasResellerLog resellerLog = new VsDramasResellerLog();
                    resellerLog.setType("indirect");
                    resellerLog.setResellerUserId(Math.toIntExact(vsUser.getParentUserId()));
                    resellerLog.setUserId(Math.toIntExact(vsUser.getId()));
                    resellerLog.setLangId(Integer.valueOf(vsLang.getId()));
                    resellerLog.setPayMoney(usableOrders.get(0).getTotalFee());
                    Map<String, String> map = JSON.parseObject(binds.get(0).getResellerJson(), new TypeReference<Map<String, String>>(){});
                    BigDecimal ratio = new BigDecimal(map.get("indirect"));
                    resellerLog.setRatio(ratio);
                    // 将其除以 100
                    BigDecimal result = ratio.divide(new BigDecimal("100"));
                    BigDecimal money = usableOrders.get(0).getTotalFee().multiply(result);
                    resellerLog.setCurrency(vsLang.getCurrency());
                    resellerLog.setExchangeRate(vsLang.getExchangeRate());
//                    money.multiply(new BigDecimal(vsLang.getExchangeRate()));
                    long l = BigDecimalUtils.calculateBigDecimalConversionToLong(money, vsLang.getExchangeRate());
                    if (l == 0) {
                        throw new Exception("BigDecimal value is out of long range.");
                    }
                    resellerLog.setMoney(BigDecimal.valueOf(l));
                    resellerLog.setTotalMoney(l);
                    resellerLog.setOrderType("vip");
                    resellerLog.setOrderId(Math.toIntExact(usableOrders.get(0).getId()));
                    resellerLog.setCreatetime(System.currentTimeMillis());
                    int vipLog = vsDramasResellerLogService.insertVsDramasResellerLog(resellerLog);
                    // 分销记录保存成功后就开始给对应用户钱包加钱
                    if (vipLog > 0) {
                        VsDramasUserWalletLog walletLog = new VsDramasUserWalletLog();
                        walletLog.setUserId(superUser.getId());
                        walletLog.setWallet(BigDecimal.valueOf(l));
                        walletLog.setWalletType("money");
                        walletLog.setType("commission_income");
                        walletLog.setBefore(superUser.getMoney());
                        walletLog.setAfter(superUser.getMoney().add(BigDecimal.valueOf(l)));
                        walletLog.setItemId(String.valueOf(usableOrders.get(0).getUsableId()));
                        walletLog.setMemo("间接分销佣金");
                        // 创建一个 JSONObject 对象，将字段值放入
                        JSONObject jsonObject = new JSONObject();
                        jsonObject.put("reseller_log_id", resellerLog.getId());
                        jsonObject.put("user_id", vsUser.getId());
                        jsonObject.put("parent_id", vsUser.getParentUserId());
                        jsonObject.put("reseller_user_id", superUser.getId());
                        // 将 JSONObject 转换为 JSON 字符串
                        String jsonString = jsonObject.toJSONString();
                        walletLog.setExt(jsonString);
                        walletLog.setOperType("system");
                        walletLog.setOperId(0L);
                        walletLog.setCreatetime(System.currentTimeMillis());
                        walletLog.setUpdatetime(System.currentTimeMillis());
                        superWalletLogs = vsDramasUserWalletLogService.insertVsDramasUserWalletLog(walletLog);
                    }
                }
                return parentWalletLogs + superWalletLogs;
            } else if ("R".equals(substring)) {
                VsDramasResellerOrder resellerOrder = new VsDramasResellerOrder();
                resellerOrder.setOrderSn(orderSn);
                List<VsDramasResellerOrder> resellerOrders = vsDramasResellerOrderMapper.selectVsDramasResellerOrderList(resellerOrder);
                VsLang vsLang = vsLangService.selectVsLangById(String.valueOf(resellerOrders.get(0).getLangId()));
                if (i == 0) {
                    VsDramasResellerLog resellerLog = new VsDramasResellerLog();
                    resellerLog.setType("direct");
                    resellerLog.setResellerUserId(Math.toIntExact(vsUser.getParentUserId()));
                    resellerLog.setUserId(Math.toIntExact(vsUser.getId()));
                    resellerLog.setLangId(Integer.valueOf(vsLang.getId()));
                    resellerLog.setPayMoney(resellerOrders.get(0).getTotalFee());
                    Map<String, String> map = JSON.parseObject(binds.get(0).getResellerJson(), new TypeReference<Map<String, String>>(){});
                    BigDecimal ratio = new BigDecimal(map.get("direct"));
                    resellerLog.setRatio(ratio);
                    // 将其除以 100
                    BigDecimal result = ratio.divide(new BigDecimal("100"));
                    BigDecimal money = resellerOrders.get(0).getTotalFee().multiply(result);
                    resellerLog.setCurrency(vsLang.getCurrency());
                    resellerLog.setExchangeRate(vsLang.getExchangeRate());
//                    money.multiply(new BigDecimal(vsLang.getExchangeRate()));
                    long l = BigDecimalUtils.calculateBigDecimalConversionToLong(money, vsLang.getExchangeRate());
                    if (l == 0) {
                        throw new Exception("BigDecimal value is out of long range.");
                    }
                    resellerLog.setMoney(BigDecimal.valueOf(l));
                    resellerLog.setTotalMoney(l);
                    resellerLog.setOrderType("vip");
                    resellerLog.setOrderId(Math.toIntExact(resellerOrders.get(0).getId()));
                    resellerLog.setCreatetime(System.currentTimeMillis());
                    int vipLog = vsDramasResellerLogService.insertVsDramasResellerLog(resellerLog);
                    // 分销记录保存成功后就开始给对应用户钱包加钱
                    if (vipLog > 0) {
                        VsDramasUserWalletLog walletLog = new VsDramasUserWalletLog();
                        walletLog.setUserId(vsUser.getParentUserId());
                        walletLog.setWallet(BigDecimal.valueOf(l));
                        walletLog.setWalletType("money");
                        walletLog.setType("commission_income");
                        walletLog.setBefore(parentUser.getMoney());
                        walletLog.setAfter(parentUser.getMoney().add(BigDecimal.valueOf(l)));
                        walletLog.setItemId(String.valueOf(resellerOrders.get(0).getResellerId()));
                        walletLog.setMemo("直接分销佣金");
                        // 创建一个 JSONObject 对象，将字段值放入
                        JSONObject jsonObject = new JSONObject();
                        jsonObject.put("reseller_log_id", resellerLog.getId());
                        jsonObject.put("user_id", vsUser.getId());
                        jsonObject.put("parent_id", vsUser.getParentUserId());
                        jsonObject.put("reseller_user_id", vsUser.getParentUserId());
                        // 将 JSONObject 转换为 JSON 字符串
                        String jsonString = jsonObject.toJSONString();
                        walletLog.setExt(jsonString);
                        walletLog.setOperType("system");
                        walletLog.setOperId(0L);
                        walletLog.setCreatetime(System.currentTimeMillis());
                        walletLog.setUpdatetime(System.currentTimeMillis());
                        parentWalletLogs = vsDramasUserWalletLogService.insertVsDramasUserWalletLog(walletLog);
                    }
                }
                if (superior == 0) {
                    VsDramasResellerLog resellerLog = new VsDramasResellerLog();
                    resellerLog.setType("indirect");
                    resellerLog.setResellerUserId(Math.toIntExact(vsUser.getParentUserId()));
                    resellerLog.setUserId(Math.toIntExact(vsUser.getId()));
                    resellerLog.setLangId(Integer.valueOf(vsLang.getId()));
                    resellerLog.setPayMoney(resellerOrders.get(0).getTotalFee());
                    Map<String, String> map = JSON.parseObject(binds.get(0).getResellerJson(), new TypeReference<Map<String, String>>(){});
                    BigDecimal ratio = new BigDecimal(map.get("indirect"));
                    resellerLog.setRatio(ratio);
                    // 将其除以 100
                    BigDecimal result = ratio.divide(new BigDecimal("100"));
                    BigDecimal money = resellerOrders.get(0).getTotalFee().multiply(result);
                    resellerLog.setCurrency(vsLang.getCurrency());
                    resellerLog.setExchangeRate(vsLang.getExchangeRate());
//                    money.multiply(new BigDecimal(vsLang.getExchangeRate()));
                    long l = BigDecimalUtils.calculateBigDecimalConversionToLong(money, vsLang.getExchangeRate());
                    if (l == 0) {
                        throw new Exception("BigDecimal value is out of long range.");
                    }
                    resellerLog.setMoney(BigDecimal.valueOf(l));
                    resellerLog.setTotalMoney(l);
                    resellerLog.setOrderType("vip");
                    resellerLog.setOrderId(Math.toIntExact(resellerOrders.get(0).getId()));
                    resellerLog.setCreatetime(System.currentTimeMillis());
                    int vipLog = vsDramasResellerLogService.insertVsDramasResellerLog(resellerLog);
                    // 分销记录保存成功后就开始给对应用户钱包加钱
                    if (vipLog > 0) {
                        VsDramasUserWalletLog walletLog = new VsDramasUserWalletLog();
                        walletLog.setUserId(superUser.getId());
                        walletLog.setWallet(BigDecimal.valueOf(l));
                        walletLog.setWalletType("money");
                        walletLog.setType("commission_income");
                        walletLog.setBefore(superUser.getMoney());
                        walletLog.setAfter(superUser.getMoney().add(BigDecimal.valueOf(l)));
                        walletLog.setItemId(String.valueOf(resellerOrders.get(0).getResellerId()));
                        walletLog.setMemo("间接分销佣金");
                        // 创建一个 JSONObject 对象，将字段值放入
                        JSONObject jsonObject = new JSONObject();
                        jsonObject.put("reseller_log_id", resellerLog.getId());
                        jsonObject.put("user_id", vsUser.getId());
                        jsonObject.put("parent_id", vsUser.getParentUserId());
                        jsonObject.put("reseller_user_id", superUser.getId());
                        // 将 JSONObject 转换为 JSON 字符串
                        String jsonString = jsonObject.toJSONString();
                        walletLog.setExt(jsonString);
                        walletLog.setOperType("system");
                        walletLog.setOperId(0L);
                        walletLog.setCreatetime(System.currentTimeMillis());
                        walletLog.setUpdatetime(System.currentTimeMillis());
                        superWalletLogs = vsDramasUserWalletLogService.insertVsDramasUserWalletLog(walletLog);
                    }
                }
                return parentWalletLogs + superWalletLogs;
            }
        } catch (Exception e) {
            log.error("分销相关操作出错", e);
            return 0;
        }
        return 0;
    }

}
